﻿#include "FITKAbaqusHDF5AdaptorJob.h"
#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"

#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Reader.h"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Writer.h"

#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractMaterial.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKAbstractSection.h"
#include "FITK_Interface/FITKInterfacePhysics/FITKSectionAssign.h"

#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignSolidHomogenous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignShellHomogeneous.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaSectionAssignBeam.h"
#include "FITK_Component/FITKAbaqusData/FITKJob.h"
#include "FITKAbaqusHDF5AdaptorJob.h"

namespace IO
{
    QString FITKAbaqusHDF5AdaptorJob::getAdaptorClass()
    {
        return "FITKAbaqusHDF5AdaptorJob";
    }

    bool FITKAbaqusHDF5AdaptorJob::adaptR()
    {
        auto job = dynamic_cast<AbaqusData::FITKJob*>(_dataObj);
        if (!_reader || !_h5Group || !job) return false;
        bool isR = true;
        isR &= readJob(job, *_h5Group);
        return isR;
    }

    bool FITKAbaqusHDF5AdaptorJob::adaptW()
    {
        auto job = dynamic_cast<AbaqusData::FITKJob*>(_dataObj);
        if (!_writer || !_h5Group || !job) return false;
        bool isW = true;
        isW &= writeJob(job, *_h5Group);
        return isW;
    }

    bool FITKAbaqusHDF5AdaptorJob::readJob(AbaqusData::FITKJob* job, H5::Group& h5Group)
    {
        if (!job) return false;
        QString name = job->getDataObjectName();
        bool isR = true;
        bool isValid = false;
        isR &= readNDataObject(job, h5Group);

        QString Desctiption = QString::fromStdString(readStrAttribute(h5Group, "Desctiption"));
        job->setDesctiption(Desctiption);

        if (!h5Group.attrExists("MutiCPU")) return false;
        bool MutiCPU = readBoolAttribute(h5Group, "MutiCPU");
        job->setIsMutiCPU(MutiCPU);

        if (!h5Group.attrExists("MutiCPUMode")) return false;
        auto sMutiCPUMode = readStrAttribute(h5Group, "MutiCPUMode");
        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::MutiCPUMode> fitkCPUMTypeTrafer;
        auto eMutiCPUMode = fitkCPUMTypeTrafer.fromString(QString::fromStdString(sMutiCPUMode), isValid);
        if (!isValid) return false;
        job->setMutiCPUMode(eMutiCPUMode);

        if (!h5Group.attrExists("NCPU")) return false;
        int NCPU = readIntAttribute(h5Group, "NCPU");
        job->setNCPU(NCPU);
        if (!h5Group.attrExists("GPU")) return false;
        bool GPU = readBoolAttribute(h5Group, "GPU");
        job->setIsGPU(GPU);
        if (!h5Group.attrExists("NGPU")) return false;
        int NGPU = readIntAttribute(h5Group, "NGPU");
        job->setNGPU(NGPU);
        if (!h5Group.attrExists("NumberOfFields")) return false;
        int NumberOfFields = readIntAttribute(h5Group, "NumberOfFields");
        job->setNumberOfFields(NumberOfFields);

        if (!h5Group.attrExists("ParallelMethod")) return false;
        auto sParallelMethod = readStrAttribute(h5Group, "ParallelMethod");
        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::ParallelMethod> fitkPMTypeTrafer;
        auto eParallelMethod = fitkPMTypeTrafer.fromString(QString::fromStdString(sParallelMethod), isValid);
        if (!isValid) return false;
        job->setParallelMethod(eParallelMethod);

        if (!h5Group.attrExists("RunningState")) return false;
        auto sRunningState = readStrAttribute(h5Group, "RunningState");
        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::RunningState> fitkRSTypeTrafer;
        auto eRunningState = fitkRSTypeTrafer.fromString(QString::fromStdString(sRunningState), isValid);
        if (!isValid) return false;
        job->setRunningState(eRunningState);

        if (!h5Group.attrExists("SolverType")) return false;
        auto sSolverType = readStrAttribute(h5Group, "SolverType");
        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::SolverType> fitkSTTypeTrafer;
        auto eSolverType = fitkSTTypeTrafer.fromString(QString::fromStdString(sSolverType), isValid);
        if (!isValid) return false;
        job->setSolveType(eSolverType);

        if (!h5Group.attrExists("FilePath")) return false;
        auto filePath = readStrAttribute(h5Group, "FilePath");
        job->setFilePath(QString::fromStdString(filePath));

        if (!h5Group.attrExists("CaseID")) return false;
        int CaseID = readIntAttribute(h5Group, "CaseID");
        job->setCaseID(CaseID);

        return isR;
    }
    bool FITKAbaqusHDF5AdaptorJob::writeJob(AbaqusData::FITKJob* job, H5::Group& h5Group)
    {
        if (!job) return false;

        std::string groupName = createParentAttribute(job, h5Group);
        if (groupName.empty())return false;
        _h5CreateGroup = h5Group.createGroup(groupName);
        bool isW = true;
        bool isValid = false;

        QString Desctiption = job->getDesctiption();
        writeStrAttribute(_h5CreateGroup, "Desctiption", Desctiption.toStdString());
        bool MutiCPU = job->isMutiCPU();
        writeBoolAttribute(_h5CreateGroup, "MutiCPU", &MutiCPU);

        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::MutiCPUMode> fitkCPUMTypeTrafer;
        auto sMutiCPUMode = fitkCPUMTypeTrafer.toStrting(job->getMutiCPUMode(), isValid);
        if (!isValid) return false;
        writeStrAttribute(_h5CreateGroup, "MutiCPUMode", sMutiCPUMode.toStdString());

        int NCPU = job->getNCPU();
        writeIntAttribute(_h5CreateGroup, "NCPU", &NCPU);
        bool GPU = job->isGPU();
        writeBoolAttribute(_h5CreateGroup, "GPU", &GPU);
        int NGPU = job->getNGPU();
        writeIntAttribute(_h5CreateGroup, "NGPU", &NGPU);
        int NumberOfFields = job->getNumberOfFields();
        writeIntAttribute(_h5CreateGroup, "NumberOfFields", &NumberOfFields);

        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::ParallelMethod> fitkPMTypeTrafer;
        auto sParallelMethod = fitkPMTypeTrafer.toStrting(job->getParallelMethod(), isValid);
        if (!isValid) return false;
        writeStrAttribute(_h5CreateGroup, "ParallelMethod", sParallelMethod.toStdString());

        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::RunningState> fitkRSTypeTrafer;
        auto sRunningState = fitkRSTypeTrafer.toStrting(job->getRunningState(), isValid);
        if (!isValid) return false;
        writeStrAttribute(_h5CreateGroup, "RunningState", sRunningState.toStdString());

        //枚举转换字符
        Core::FITKEnumTransfer<AbaqusData::FITKJob::SolverType> fitkJTypeTrafer;
        auto sSolverType = fitkJTypeTrafer.toStrting(job->getSolverType(), isValid);
        if (!isValid) return false;
        writeStrAttribute(_h5CreateGroup, "SolverType", sSolverType.toStdString());


        QString filePath = job->getFilePath();
        writeStrAttribute(_h5CreateGroup, "FilePath", filePath.toStdString());

        int CaseID = job->getCaseID();
        writeIntAttribute(_h5CreateGroup, "CaseID", &CaseID);
        isW &= writeNDataObject(job, _h5CreateGroup);
        return isW;
    }
}